//
//  RunLoopSource.m
//  adsx
//
//  Created by wp w on 12-6-16.
//  Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
//

#import "RunLoopSource.h"
#import "AppDelegate.h"
#import "DLog.h"

@implementation RunLoopSource
@synthesize delegate;

void RunLoopSourceScheduleRoutine (void *info, CFRunLoopRef rl, CFStringRef mode)
{
    DLogFun();
    RunLoopSource* obj = (RunLoopSource*)info;
    RunLoopContext* theContext = [[RunLoopContext alloc] initWithSource:obj andLoop:rl];
    
    [obj.delegate performSelectorOnMainThread:@selector(registerSource:)
                          withObject:theContext waitUntilDone:NO];
}

void RunLoopSourcePerformRoutine (void *info)
{
    DLogFun();
    RunLoopSource*  obj = (RunLoopSource*)info;
    [obj sourceFired];
}

void RunLoopSourceCancelRoutine (void *info, CFRunLoopRef rl, CFStringRef mode)
{
    DLogFun();
    RunLoopSource* obj = (RunLoopSource*)info;
    RunLoopContext* theContext = [[RunLoopContext alloc] initWithSource:obj andLoop:rl];
    
    [obj.delegate performSelectorOnMainThread:@selector(removeSource:)
                          withObject:theContext waitUntilDone:YES];
}

-(id)initWithDelegate:(ViewController *)dele
{
    DLogFun();
    self=[super init];
    if (self)
    {
        CFRunLoopSourceContext context = {0, self, NULL, NULL, NULL, NULL, NULL,
            &RunLoopSourceScheduleRoutine,
            &RunLoopSourceCancelRoutine,
            &RunLoopSourcePerformRoutine};
        
        runLoopSource = CFRunLoopSourceCreate(NULL, 0, &context);
        commands = [[NSMutableArray alloc] init];
        [dele retain];
        [delegate release];
        delegate = dele;
    }
    
    return self;
}

- (void)addToCurrentRunLoop
{
    DLogFun();
    CFRunLoopRef runLoop = CFRunLoopGetCurrent();
    CFRunLoopAddSource(runLoop, runLoopSource, kCFRunLoopDefaultMode);
}

- (void)invalidate
{
    DLogFun();
    CFRunLoopSourceInvalidate(runLoopSource);
}

- (void)removeFromCurrentRunLoop
{
    DLogFun();
    CFRunLoopRef runLoop = CFRunLoopGetCurrent();
    CFRunLoopRemoveSource(runLoop, runLoopSource, kCFRunLoopDefaultMode);
}

- (void)sourceFired
{
    DLogFun();
    NSLog(@"%@",commands);
}

- (void)addCommand:(NSInteger)command withData:(id)data
{
    DLogFun();
    [commands insertObject:data atIndex:command];
    NSLog(@"%@",commands);
}

- (void)fireCommandsOnRunLoop:(CFRunLoopRef)runloop
{
    DLogFun();
    CFRunLoopSourceSignal(runLoopSource);
    CFRunLoopWakeUp(runloop);
}

- (void)fireCommandsOnRunLoop
{
    DLogFun();
    CFRunLoopRef runLoop = CFRunLoopGetCurrent();
    CFRunLoopSourceSignal(runLoopSource);
    CFRunLoopWakeUp(runLoop);
}

-(void)dealloc
{
    DLogFun();
    CFRelease(runLoopSource);
    [commands release];
    [delegate release];
    [super dealloc];
}

@end

@implementation RunLoopContext
@synthesize runLoop;
@synthesize source;

-(id)initWithSource:(RunLoopSource *)src andLoop:(CFRunLoopRef)loop
{
//    DLogFun();
    self = [super init];
    if (self) {
        runLoop = loop;
        source = src;
    }
    return self;
}

@end
